package com.demo.config;


import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.concurrent.*;

/**
 * @author : YU.TAN
 * @date : 2021/8/20 18:18
 */
@Component
public class ThreadPoolManager {


    @Bean("ThreadPool")
    public ThreadPoolManager.ThreadPool getThreadPoolBean(){
        return ThreadPoolManager.getInstance();
    }

    /**
     * volatile 保证每次读取对象都是在主内存中读取
     */
    private volatile static ThreadPool instance;

    /**
     * 私有化构造方法，阻止外部直接实例化对象
     */
    private ThreadPoolManager() {
    }

    /**
     * 获取线程池对象， 双重校验式单利
     * @return
     */
    public static ThreadPool getInstance() {
        if (instance == null) {
            synchronized (ThreadPoolManager.class) {
                if (instance == null) {
                    int cpuNum = Runtime.getRuntime().availableProcessors();

                    int threadNum = cpuNum * 2 + 1;

                    instance = new ThreadPool(threadNum - 1, threadNum, 60);

                }
            }
        }
        return instance;
    }


    public static class ThreadPool<T> {
        private ThreadPoolExecutor executor;
        /**
         * 核心线程数
         */
        private int corePoolSize;
        /**
         * 最大线程数
         */
        private int maxPoolSize;
        /**
         * 空闲线程存活时间
         */
        private long keepAliveTime;

        /**
         * 线程池构造函数
         * @param corePoolSize
         * @param maxPoolSize
         * @param keepAliveTime
         */
        private ThreadPool(int corePoolSize, int maxPoolSize, long keepAliveTime) {
            this.corePoolSize = corePoolSize;
            this.maxPoolSize = maxPoolSize;
            this.keepAliveTime = keepAliveTime;
        }

        /**
         * 判断线程池实例是否为空，为空则创建线程池实例
         */
        private void initializeTheThreadPool() {
            if (executor == null) {
                //创建线程池
                executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS,
                        //线程等待队列
                        new LinkedBlockingDeque<Runnable>(Integer.MAX_VALUE),
                        //默认线程工厂
                        Executors.defaultThreadFactory(),
                        //线程池拒绝策略
                        new ThreadPoolExecutor.AbortPolicy());
            }
        }

        /**
         * 向线程池提交一个任务，返回线程结果
         * @param c
         * @return
         */
        public Future<T> submit(Callable<T> c) {
            if (c == null) {
                throw new NullPointerException();
            }
            initializeTheThreadPool();
            return executor.submit(c);
        }

        /**
         * 向线程池提交一个任务，不返回结果
         * @param r
         */
        public void execute(Runnable r){
            if (r == null) {
                throw new NullPointerException();
            }
            initializeTheThreadPool();
            executor.execute(r);
        }

        /**
         * 获取活动线程池数量
         * @return
         */
        public int getSize(){
            return executor.getActiveCount();
        }

        /**
         * 从线程等待队列中移除对象
         * @param runnable
         */
        public void cancel(Runnable runnable){
            if (executor!=null){
                executor.getQueue().remove(runnable);
            }
        }

    }

}
